package org.argus.common.mybatis.interceptor;

import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.argus.common.core.token.ITokenManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;

/**
 * 新增修改增加 时间 戳发起人 拦截器
 *
 * @Author 刘文/Cliff Liu
 * @Date 2024/7/21
 */
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {java.sql.Connection.class, Integer.class})})
@Component
@Slf4j
public class InsertUpdateInterceptor implements Interceptor {

    /**
     * 创建时间字段
     */
    public static final String CREATE_TIME_COLUMN = "create_time";

    /**
     * 修改时间字段
     */
    public static final String UPDATE_TIME_COLUMN = "update_time";

    /**
     * 创建人字段
     */
    public static final String CREATED_BY_COLUMN = "created_by";

    /**
     * 最后修改人字段
     */
    public static final String UPDATED_BY_COLUMN = "updated_by";

    @Autowired
    private ITokenManager tokenManager;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");
        if (SqlCommandType.UPDATE != mappedStatement.getSqlCommandType()) {
            return invocation.proceed();
        }
        BoundSql boundSql = (BoundSql)metaObject.getValue("delegate.boundSql");
        String sql = boundSql.getSql();
        if (sql.indexOf(UPDATE_TIME_COLUMN) == -1) {
            sql = sql.replaceFirst("SET",
                "SET " + UPDATE_TIME_COLUMN + " = '" + new Timestamp(System.currentTimeMillis()) + "',");
        }
        if (sql.indexOf(UPDATED_BY_COLUMN) == -1) {
            sql = sql.replaceFirst("SET",
                "SET " + UPDATED_BY_COLUMN + " = " + tokenManager.getUserId() + ",");
        }
        metaObject.setValue("delegate.boundSql.sql", sql);
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {

        return Interceptor.super.plugin(target);
    }
}
